WebGL ì °ìŽë ë§€ê°ë³ì êŽëЬì ëí í¬êŽì ìž ê°ìŽëë¡, ì °ìŽë ìí ìì€í , ì ëíŒ ì²ëЬ ë° ê³ ì±ë¥ ë ëë§ì ìí ìµì í êž°ë²ì ë€ë£¹ëë€.
WebGL ì °ìŽë ë§€ê°ë³ì êŽëЬì: ìµì íë ë ëë§ì ìí ì °ìŽë ìí ë§ì€í°ë§
WebGL ì °ìŽëë 3D ì¥ë©Žì ë³ííê³ ë ëë§íë ìí ì ëŽë¹íë ìµì ì¹ êž°ë° ê·žëíœì íµì¬ì ëë€. ì °ìŽë ë§€ê°ë³ì(ì ëíŒ ë° ìì±)륌 íšìšì ìŒë¡ êŽëЬíë ê²ì ìµì ì ì±ë¥ê³Œ ìê°ì ì¶©ì€ë륌 ë¬ì±íë ë° ë§€ì° ì€ìí©ëë€. ìŽ í¬êŽì ìž ê°ìŽëììë ê°ë ¥í ì °ìŽë ìí ìì€í 구ì¶ì ì€ì ì ëê³ WebGL ì °ìŽë ë§€ê°ë³ì êŽëЬ ë€ì ìë ê°ë 곌 êž°ì ì ìŽíŽëŽ ëë€.
ì °ìŽë ë§€ê°ë³ì ìŽíŽ
êŽëЬ ì ëµì ëíŽ ììží ìì볎Ʞ ì ì ì °ìŽëê° ì¬ì©íë ë§€ê°ë³ì ì íì ìŽíŽíë ê²ìŽ íìì ì ëë€.
- ì ëíŒ: ëšìŒ 귞늬Ʞ ížì¶ì ëíŽ ìììž ì ì ë³ìì ëë€. ìŒë°ì ìŒë¡ íë ¬, ìì ë° í ì€ì²ì ê°ì ë°ìŽí°ë¥Œ ì ë¬íë ë° ì¬ì©ë©ëë€.
- ìì±: ë ëë§ëë íìì ë°ëŒ ë€ë¥ž ì ì ë³ ë°ìŽí°ì ëë€. ìë¡ë ì ì ìì¹, ë²ì ë° í ì€ì² ì¢íê° ììµëë€.
- ë³ì: ì ì ì °ìŽëìì íëê·žëšŒíž ì °ìŽëë¡ ì ë¬ëìŽ ë ëë§ë Ʞ볞 ìì ì 첎ì 볎ê°ë ê°ì ëë€.
ì ëíŒì ì±ë¥ êŽì ìì í¹í ì€ìíë©°, ìŽë¥Œ ì€ì íë ìì ìë CPU(JavaScript)ì GPU(ì °ìŽë íë¡ê·žëš) ê°ì íµì ìŽ í¬íšë©ëë€. ë¶íìí ì ëíŒ ì ë°ìŽížë¥Œ ìµìííë ê²ìŽ ì£Œì ìµì í ì ëµì ëë€.
ì °ìŽë ìí êŽëЬì 곌ì
ë³µì¡í WebGL ì í늬ìŒìŽì ìì ì °ìŽë ë§€ê°ë³ì륌 êŽëЬíë ìì ì ë¹ ë¥Žê² ë² ì°° ì ììµëë€. ë€ì ìë늬ì€ë¥Œ ê³ ë €íŽ ë³Žììì€.
- ì¬ë¬ ì °ìŽë: ì¥ë©Žì ìë ë€ë¥ž ê°ì²Žë ì첎 ì ëíŒ ì§í©ìŽ ìë ë€ë¥ž ì °ìŽë륌 íìë¡ í ì ììµëë€.
- ê³µì 늬ìì€: ì¬ë¬ ì °ìŽëê° ëìŒí í ì€ì² ëë íë ¬ì ì¬ì©í ì ììµëë€.
- ëì ì ë°ìŽíž: ì ëíŒ ê°ì ì¬ì©ì ìíž ìì©, ì ëë©ìŽì ëë êž°í ì€ìê° ìì륌 êž°ë°ìŒë¡ ì죌 ë³ê²œë©ëë€.
- ìí ì¶ì : ìŽë€ ì ëíŒìŽ ì€ì ëìê³ ì ë°ìŽížê° íìíì§ ì¶ì íë ìì ì ë³µì¡íŽì§ê³ ì€ë¥ê° ë°ìíêž° ì¬ìì§ ì ììµëë€.
ì ì€ê³ë ìì€í ìŽ ììŒë©Ž ìŽë¬í 곌ì ë¡ ìžíŽ ë€ì곌 ê°ì 묞ì ê° ë°ìí ì ììµëë€.
- ì±ë¥ ë³ëª© íì: ë¹ë²íê³ ì€ë³µë ì ëíŒ ì ë°ìŽížë íë ì ìëì ìë¹í ìí¥ì ë¯žì¹ ì ììµëë€.
- ìœë ì€ë³µ: ì¬ë¬ ìì¹ìì ëìŒí ì ëíŒì ì€ì í멎 ìœë륌 ì ì§ êŽëЬíêž°ê° ë ìŽë €ìì§ëë€.
- ë²ê·ž: ìŒêŽì± ìë ìí êŽëЬë ë ëë§ ì€ë¥ì ìê°ì ìí°í©ížë¡ ìŽìŽì§ ì ììµëë€.
ì °ìŽë ìí ìì€í 구ì¶
ì °ìŽë ìí ìì€í ì ì °ìŽë ë§€ê°ë³ì륌 êŽëЬíêž° ìí 구조íë ì ê·Œ ë°©ìì ì ê³µíì¬ ì€ë¥ ìíì ì€ìŽê³ ì±ë¥ì í¥ììíµëë€. ë€ìì ìŽë¬í ìì€í ì 구ì¶íêž° ìí ëšê³ë³ ê°ìŽëì ëë€.
1. ì °ìŽë íë¡ê·žëš ì¶ìí
WebGL ì °ìŽë íë¡ê·žëšì JavaScript íŽëì€ ëë ê°ì²Ž ëŽì 캡ìíí©ëë€. ìŽ ì¶ìíë ë€ìì ì²ëЬíŽìŒ í©ëë€.
- ì °ìŽë 컎íìŒ: ì ì ë° íëê·žëšŒíž ì °ìŽë륌 íë¡ê·žëšìŒë¡ 컎íìŒí©ëë€.
- ìì± ë° ì ëíŒ ìì¹ ê²ì: íšìšì ìž ì¡ìžì€ë¥Œ ìíŽ ìì± ë° ì ëíŒ ìì¹ë¥Œ ì ì¥í©ëë€.
- íë¡ê·žëš íì±í:
gl.useProgram()ì ì¬ì©íì¬ ì °ìŽë íë¡ê·žëšìŒë¡ ì íí©ëë€.
ì:
class ShaderProgram {
constructor(gl, vertexShaderSource, fragmentShaderSource) {
this.gl = gl;
this.program = this.createProgram(vertexShaderSource, fragmentShaderSource);
this.uniformLocations = {};
this.attributeLocations = {};
}
createProgram(vertexShaderSource, fragmentShaderSource) {
const vertexShader = this.createShader(this.gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, fragmentShaderSource);
const program = this.gl.createProgram();
this.gl.attachShader(program, vertexShader);
this.gl.attachShader(program, fragmentShader);
this.gl.linkProgram(program);
if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) {
console.error('Unable to initialize the shader program: ' + this.gl.getProgramInfoLog(program));
return null;
}
return program;
}
createShader(type, source) {
const shader = this.gl.createShader(type);
this.gl.shaderSource(shader, source);
this.gl.compileShader(shader);
if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
console.error('An error occurred compiling the shaders: ' + this.gl.getShaderInfoLog(shader));
this.gl.deleteShader(shader);
return null;
}
return shader;
}
use() {
this.gl.useProgram(this.program);
}
getUniformLocation(name) {
if (!this.uniformLocations[name]) {
this.uniformLocations[name] = this.gl.getUniformLocation(this.program, name);
}
return this.uniformLocations[name];
}
getAttributeLocation(name) {
if (!this.attributeLocations[name]) {
this.attributeLocations[name] = this.gl.getAttribLocation(this.program, name);
}
return this.attributeLocations[name];
}
}
2. ì ëíŒ ë° ìì± êŽëЬ
ì ëíŒ ë° ìì± ê°ì ì€ì íêž° ìíŽ `ShaderProgram` íŽëì€ì ë©ìë륌 ì¶ê°í©ëë€. ìŽë¬í ë©ìëë ë€ìì ìííŽìŒ í©ëë€.
- ì ëíŒ/ìì± ìì¹ ì§ì° ê²ì: ì ëíŒ/ìì±ìŽ ì²ì ì€ì ë ëë§ ìì¹ë¥Œ ê²ìí©ëë€. ìì ìì ë ìŽë¯ž ìŽ ìì ì ìíí©ëë€.
- ì ì í
gl.uniform*ëëgl.vertexAttrib*íšìë¡ ëì€íšì¹: ì€ì ëë ê°ì ë°ìŽí° ì íì ë°ëŒ ë€ëŠ ëë€. - ì íì ìŒë¡ ì ëíŒ ìí ì¶ì : ë¶íìí ì ë°ìŽížë¥Œ ë°©ì§íêž° ìíŽ ê° ì ëíŒì ëíŽ ë§ì§ë§ìŒë¡ ì€ì ë ê°ì ì ì¥í©ëë€.
ì (ìŽì `ShaderProgram` íŽëì€ íì¥):
class ShaderProgram {
// ... (previous code) ...
uniform1f(name, value) {
const location = this.getUniformLocation(name);
if (location) {
this.gl.uniform1f(location, value);
}
}
uniform3fv(name, value) {
const location = this.getUniformLocation(name);
if (location) {
this.gl.uniform3fv(location, value);
}
}
uniformMatrix4fv(name, value) {
const location = this.getUniformLocation(name);
if (location) {
this.gl.uniformMatrix4fv(location, false, value);
}
}
vertexAttribPointer(name, size, type, normalized, stride, offset) {
const location = this.getAttributeLocation(name);
if (location !== null && location !== undefined) { // Check if the attribute exists in the shader
this.gl.vertexAttribPointer(
location,
size,
type,
normalized,
stride,
offset
);
this.gl.enableVertexAttribArray(location);
}
}
}
ë¶íìí ì ë°ìŽížë¥Œ ë°©ì§íêž° ìíŽ ìí륌 ì¶ì íëë¡ ìŽ íŽëì€ë¥Œ ì¶ê°ë¡ íì¥:
class ShaderProgram {
// ... (previous code) ...
constructor(gl, vertexShaderSource, fragmentShaderSource) {
this.gl = gl;
this.program = this.createProgram(vertexShaderSource, fragmentShaderSource);
this.uniformLocations = {};
this.attributeLocations = {};
this.uniformValues = {}; // Track the last set uniform values
}
uniform1f(name, value) {
const location = this.getUniformLocation(name);
if (location && this.uniformValues[name] !== value) {
this.gl.uniform1f(location, value);
this.uniformValues[name] = value;
}
}
uniform3fv(name, value) {
const location = this.getUniformLocation(name);
// Compare array values for changes
if (location && (!this.uniformValues[name] || !this.arraysAreEqual(this.uniformValues[name], value))) {
this.gl.uniform3fv(location, value);
this.uniformValues[name] = Array.from(value); // Store a copy to avoid modification
}
}
uniformMatrix4fv(name, value) {
const location = this.getUniformLocation(name);
if (location && (!this.uniformValues[name] || !this.arraysAreEqual(this.uniformValues[name], value))) {
this.gl.uniformMatrix4fv(location, false, value);
this.uniformValues[name] = Array.from(value); // Store a copy to avoid modification
}
}
arraysAreEqual(a, b) {
if (a === b) return true;
if (a == null || b == null) return false;
if (a.length !== b.length) return false;
for (let i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false;
}
return true;
}
vertexAttribPointer(name, size, type, normalized, stride, offset) {
const location = this.getAttributeLocation(name);
if (location !== null && location !== undefined) { // Check if the attribute exists in the shader
this.gl.vertexAttribPointer(
location,
size,
type,
normalized,
stride,
offset
);
this.gl.enableVertexAttribArray(location);
}
}
}
3. ì¬ì§ ìì€í
ì¬ì§ ìì€í ì ê°ì²Žì ìê°ì ìì±ì ì ìí©ëë€. ê° ì¬ì§ì `ShaderProgram`ì ì°žì¡°íê³ íìí ì ëíŒì ëí ê°ì ì ê³µíŽìŒ í©ëë€. ìŽë¥Œ íµíŽ ë€ë¥ž ë§€ê°ë³ì륌 ì¬ì©íì¬ ì °ìŽë륌 ìœê² ì¬ì¬ì©í ì ììµëë€.
ì:
class Material {
constructor(shaderProgram, uniforms) {
this.shaderProgram = shaderProgram;
this.uniforms = uniforms;
}
apply() {
this.shaderProgram.use();
for (const name in this.uniforms) {
const value = this.uniforms[name];
if (typeof value === 'number') {
this.shaderProgram.uniform1f(name, value);
} else if (Array.isArray(value) && value.length === 3) {
this.shaderProgram.uniform3fv(name, value);
} else if (value instanceof Float32Array && value.length === 16) {
this.shaderProgram.uniformMatrix4fv(name, value);
} // Add more type checks as needed
else if (value instanceof WebGLTexture) {
// Handle texture setting (example)
const textureUnit = 0; // Choose a texture unit
gl.activeTexture(gl.TEXTURE0 + textureUnit); // Activate the texture unit
gl.bindTexture(gl.TEXTURE_2D, value);
gl.uniform1i(this.shaderProgram.getUniformLocation(name), textureUnit); // Set the sampler uniform
} // Example for textures
}
}
}
4. ë ëë§ íìŽíëŒìž
ë ëë§ íìŽíëŒìžì ì¥ë©Žì ê°ì²Žë¥Œ ë°ë³µíê³ ê° ê°ì²Žì ëíŽ ë€ìì ìííŽìŒ í©ëë€.
material.apply()륌 ì¬ì©íì¬ íì± ì¬ì§ì ì€ì í©ëë€.- ê°ì²Žì ì ì ë²íŒ ë° ìžë±ì€ ë²íŒë¥Œ ë°ìžë©í©ëë€.
gl.drawElements()ëëgl.drawArrays()륌 ì¬ì©íì¬ ê°ì²Žë¥Œ 귞늜ëë€.
ì:
function render(gl, scene, camera) {
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
const viewMatrix = camera.getViewMatrix();
const projectionMatrix = camera.getProjectionMatrix(gl.canvas.width / gl.canvas.height);
for (const object of scene.objects) {
const modelMatrix = object.getModelMatrix();
const material = object.material;
material.apply();
// Set common uniforms (e.g., matrices)
material.shaderProgram.uniformMatrix4fv('uModelMatrix', modelMatrix);
material.shaderProgram.uniformMatrix4fv('uViewMatrix', viewMatrix);
material.shaderProgram.uniformMatrix4fv('uProjectionMatrix', projectionMatrix);
// Bind vertex buffers and draw
gl.bindBuffer(gl.ARRAY_BUFFER, object.vertexBuffer);
material.shaderProgram.vertexAttribPointer('aVertexPosition', 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, object.indexBuffer);
gl.drawElements(gl.TRIANGLES, object.indices.length, gl.UNSIGNED_SHORT, 0);
}
}
ìµì í êž°ë²
ì °ìŽë ìí ìì€í ì 구ì¶íë ê² ìžìë ë€ì ìµì í êž°ë²ì ê³ ë €íììì€.
- ì ëíŒ ì ë°ìŽíž ìµìí: ììì ì€ëª í ê²ì²ëŒ ê° ì ëíŒì ëíŽ ë§ì§ë§ìŒë¡ ì€ì ë ê°ì ì¶ì íê³ ê°ìŽ ë³ê²œë 겜ì°ìë§ ì ë°ìŽíží©ëë€.
- ì ëíŒ ëžë¡ ì¬ì©: êŽë š ì ëíŒì ì ëíŒ ëžë¡ìŒë¡ 귞룹ííì¬ ê°ë³ ì ëíŒ ì ë°ìŽížì ì€ë²í€ë륌 ì€ì ëë€. ê·žë¬ë 구íì í¬ê² ë€ë¥Œ ì ììŒë©° ëžë¡ì ì¬ì©íë€ê³ íŽì ì±ë¥ìŽ íì í¥ìëë ê²ì ìëëë€. í¹ì ì¬ì© ì¬ë¡ë¥Œ ë²€ì¹ë§í¹í©ëë€.
- 귞늬Ʞ ížì¶ ìŒêŽ ì²ëЬ: ëìŒí ì¬ì§ì ì¬ì©íë ì¬ë¬ ê°ì²Žë¥Œ ëšìŒ 귞늬Ʞ ížì¶ë¡ ê²°í©íì¬ ìí ë³ê²œì ì€ì ëë€. ìŽë 몚ë°ìŒ íë«íŒìì í¹í ì ì©í©ëë€.
- ì °ìŽë ìœë ìµì í: ì °ìŽë ìœë륌 íë¡íìŒë§íì¬ ì±ë¥ ë³ëª© íìì ìë³íê³ ê·žì ë°ëŒ ìµì íí©ëë€.
- í ì€ì² ìµì í: ASTC ëë ETC2ì ê°ì ìì¶ë í ì€ì² íìì ì¬ì©íì¬ í ì€ì² ë©ëªšëЬ ì¬ì©ëì ì€ìŽê³ ë¡ë© ìê°ì ê°ì í©ëë€. ë©ëЬ ìë ê°ì²Žì ë ëë§ íì§ê³Œ ì±ë¥ì í¥ììí€êž° ìíŽ ë°ë§µì ìì±í©ëë€.
- ìžì€íŽì€í: ìžì€íŽì€í륌 ì¬ì©íì¬ ìë¡ ë€ë¥ž ë³íìŒë¡ ëìŒí íìì ì¬ë¬ ë³µì¬ë³žì ë ëë§íì¬ ê·žëŠ¬êž° ížì¶ ì륌 ì€ì ëë€.
êžë¡ë² ê³ ë € ì¬í
êžë¡ë² ì€ëìžì€ë¥Œ ìíŽ WebGL ì í늬ìŒìŽì ì ê°ë°í ë ë€ì ê³ ë € ì¬íì ìŒëì ëììì€.
- ì¥ì¹ ë€ìì±: ì ê°í íŽëí° ë° ê³ êž ë°ì€í¬í±ì í¬íší êŽë²ìí ì¥ì¹ìì ì í늬ìŒìŽì ì í ì€íží©ëë€.
- ë€ížìí¬ í겜: ë€ìí ë€ížìí¬ ìëìì íšìšì ìž ì ë¬ì ìíŽ ìì°(í ì€ì², 몚ëž, ì °ìŽë)ì ìµì íí©ëë€.
- íì§í: ì í늬ìŒìŽì ì í ì€íž ëë êž°í ì¬ì©ì ìží°íìŽì€ ììê° í¬íšë ê²œì° ë€ìí ìžìŽì ë§ê² ì ì íê² íì§íëìëì§ íìží©ëë€.
- ì ê·Œì±: ì¥ì ê° ìë ì¬ì©ìê° ì í늬ìŒìŽì ì ì¬ì©í ì ìëë¡ ì ê·Œì± ì§ì¹šì ê³ ë €í©ëë€.
- ìœí ìž ì ì¡ ë€ížìí¬(CDN): CDNì íì©íì¬ ì ìžê³ì ìŒë¡ ìì°ì ë°°í¬íì¬ ì ìžê³ ì¬ì©ìì ë¹ ë¥ž ë¡ë© ìê°ì 볎ì¥í©ëë€. ìžêž° ìë ì íìŒë¡ë AWS CloudFront, Cloudflare ë° Akamaiê° ììµëë€.
ê³ êž êž°ì
1. ì °ìŽë ë³í
ë€ë¥ž ë ëë§ êž°ë¥ ëë ë€ë¥ž íëìšìŽ êž°ë¥ì ì§ìíêž° ìíŽ ì °ìŽëì ë€ë¥ž ë²ì (ì °ìŽë ë³í)ì ë§ëëë€. ì륌 ë€ìŽ ê³ êž ì¡°ëª íšê³Œê° ìë ê³ íì§ ì °ìŽëì ë ê°ëší ì¡°ëª ìŽ ìë ì íì§ ì °ìŽëê° ìì ì ììµëë€.
2. ì °ìŽë ì¬ì ì²ëЬ
컎íìŒ ì ì ìœë ë³í ë° ìµì í륌 ìííêž° ìíŽ ì °ìŽë ì¬ì ì²ëŠ¬êž°ë¥Œ ì¬ì©í©ëë€. ì¬êž°ìë íšì ìžëŒìž, ì¬ì©íì§ ìë ìœë ì ê±° ë° ë€ë¥ž ì °ìŽë ë³í ìì±ìŽ í¬íšë ì ììµëë€.
3. ë¹ëêž° ì °ìŽë 컎íìŒ
죌 ì€ë ë륌 ì°šëšíì§ ìëë¡ ì °ìŽë륌 ë¹ëêž°ì ìŒë¡ 컎íìŒí©ëë€. ìŽë í¹í ìŽêž° ë¡ë© ì€ì ì í늬ìŒìŽì ì ìëµì±ì í¥ììí¬ ì ììµëë€.
4. 컎íšíž ì °ìŽë
GPUìì ë²ì© ê³ì°ì 컎íšíž ì °ìŽë륌 íì©í©ëë€. ìŽë ì ì ìì€í ì ë°ìŽíž, ìŽë¯žì§ ì²ëЬ ë° ë¬ŒëŠ¬ ì뮬ë ìŽì 곌 ê°ì ìì ì ì ì©í ì ììµëë€.
ëë²ê¹ ë° íë¡íìŒë§
WebGL ì °ìŽë륌 ëë²ê¹ íë ê²ì ìŽë €ìž ì ìì§ë§ ëììŽ ëë ëª ê°ì§ ëêµ¬ê° ììµëë€.
- ëžëŒì°ì ê°ë°ì ë구: ëžëŒì°ì ì ê°ë°ì ë구륌 ì¬ì©íì¬ WebGL ìí, ì °ìŽë ìœë ë° íë ì ë²íŒë¥Œ ê²ì¬í©ëë€.
- WebGL Inspector: WebGL ížì¶ì ëšê³ë³ë¡ ì€ííê³ , ì °ìŽë ë³ì륌 ê²ì¬íê³ , ì±ë¥ ë³ëª© íìì ìë³í ì ìë ëžëŒì°ì íì¥ íë¡ê·žëšì ëë€.
- RenderDoc: íë ì 캡ì², ì °ìŽë ëë²ê¹ ë° ì±ë¥ ë¶ì곌 ê°ì ê³ êž êž°ë¥ì ì ê³µíë ë 늜í ê·žëíœ ëë²ê±°ì ëë€.
ì±ë¥ ë³ëª© íìì ìë³íë €ë©Ž WebGL ì í늬ìŒìŽì ì íë¡íìŒë§íë ê²ìŽ ì€ìí©ëë€. ëžëŒì°ì ì ì±ë¥ íë¡íìŒë¬ ëë í¹ì WebGL íë¡íìŒë§ ë구륌 ì¬ì©íì¬ íë ì ìë, 귞늬Ʞ ížì¶ ì ë° ì °ìŽë ì€í ìê°ì ìž¡ì í©ëë€.
ì€ì ì¬ë¡
ëªëª ì€í ìì€ WebGL ëŒìŽëžë¬ëЬ ë° íë ììí¬ë ê°ë ¥í ì °ìŽë êŽëЬ ìì€í ì ì ê³µí©ëë€. ë€ìì ëª ê°ì§ ìì ëë€.
- Three.js: ì °ìŽë êŽëЬ ë° ì¬ì§ ìì€í ì í¬íšíì¬ WebGLì ëí ê³ êž ì¶ìí륌 ì ê³µíë ìžêž° ìë JavaScript 3D ëŒìŽëžë¬ëЬì ëë€.
- Babylon.js: 묌늬 êž°ë° ë ëë§(PBR) ë° ì¥ë©Ž ê·žëí êŽëЬì ê°ì ê³ êž êž°ë¥ì ê°ì¶ ë ë€ë¥ž í¬êŽì ìž JavaScript 3D íë ììí¬ì ëë€.
- PlayCanvas: ìê°ì ížì§êž°ê° ììŒë©° ì±ë¥ê³Œ íì¥ì±ì ì€ì ì ë WebGL ê²ì ìì§ì ëë€.
- PixiJS: WebGL(Canvas íŽë°± í¬íš)ì ì¬ì©íê³ ë³µì¡í ìê° íšê³Œë¥Œ ë§ëë ë° ê°ë ¥í ì °ìŽë ì§ìì í¬íšíë 2D ë ëë§ ëŒìŽëžë¬ëЬì ëë€.
ê²°ë¡
íšìšì ìž WebGL ì °ìŽë ë§€ê°ë³ì êŽëЬë ê³ ì±ë¥ì ìê°ì ìŒë¡ ëëŒìŽ ì¹ êž°ë° ê·žëíœ ì í늬ìŒìŽì ì ë§ëë ë° íìì ì ëë€. ì °ìŽë ìí ìì€í ì 구ííê³ , ì ëíŒ ì ë°ìŽížë¥Œ ìµìííê³ , ìµì í êž°ì ì íì©íì¬ ìœëì ì±ë¥ê³Œ ì ì§ êŽëЬì±ì í¬ê² í¥ììí¬ ì ììµëë€. êžë¡ë² ì€ëìžì€ë¥Œ ìíŽ ì í늬ìŒìŽì ì ê°ë°í ë ì¥ì¹ ë€ìì± ë° ë€ížìí¬ í겜곌 ê°ì êžë¡ë² ìì륌 ê³ ë €íììì€. ì °ìŽë ë§€ê°ë³ì êŽëЬì ì¬ì© ê°ë¥í ë구 ë° êž°ì ì ëí íì€í ìŽíŽë¥Œ íµíŽ WebGLì 몚ë ì ì¬ë ¥ì íì©íê³ ì ìžê³ ì¬ì©ì륌 ìí 몰ì í 겜íì ë§ë€ ì ììµëë€.